import tkinter as tk
from tkinter import messagebox, simpledialog, filedialog
import pandas as pd

class Course:
    def __init__(self, course_name, credits, grade, is_repeated=False):
        self.course_name = course_name
        self.credits = credits
        self.grade = grade
        self.is_repeated = is_repeated

    def __str__(self):
        return f"课程名称：{self.course_name}, 学分：{self.credits}, 成绩：{self.grade}, 是否重修：{self.is_repeated}"


class StudentInfo:
    def __init__(self, student_id, name, department, class_name):
        self.student_id = student_id
        self.name = name
        self.department = department
        self.class_name = class_name


class AcademicData:
    def __init__(self):
        self.courses_taken = []  # 已修课程信息列表
        self.gpa = 0.0  # 平均学分绩点
        self.failed_credits = 0  # 累计不及格课程总学分

    def add_course(self, course):
        self.courses_taken.append(course)
        self.update_gpa()
        self.update_failed_credits()

    def update_gpa(self):
        total_points = 0
        total_credits = 0
        for course in self.courses_taken:
            if course.grade >= 60:  # 假设60分为及格
                # 根据成绩计算绩点，这里简单示例，实际应根据学校规定计算
                if course.grade >= 90:
                    points = 4.0
                elif course.grade >= 80:
                    points = 3.0
                elif course.grade >= 70:
                    points = 2.0
                elif course.grade >= 60:
                    points = 1.0
                else:
                    points = 0.0
                total_points += points * course.credits
                total_credits += course.credits
        if total_credits > 0:
            self.gpa = total_points / total_credits
        else:
            self.gpa = 0.0

    def update_failed_credits(self):
        self.failed_credits = sum(course.credits for course in self.courses_taken if course.grade < 60)
    def add_course(self, course):
        # 检查课程是否已经存在
        existing_course = next((c for c in self.courses_taken if c.course_name == course.course_name), None)
        if existing_course:
            # 如果课程已存在，更新课程信息
            existing_course.credits = course.credits
            existing_course.grade = course.grade
            existing_course.is_repeated = course.is_repeated
        else:
            # 如果课程不存在，添加新课程
            self.courses_taken.append(course)
        # 更新GPA和不及格课程总学分
        self.update_gpa()
        self.update_failed_credits()


class Student:
    def __init__(self, student_info, academic_data):
        self.student_info = student_info
        self.academic_data = academic_data

    def __str__(self):
        return f"学号：{self.student_info.student_id}, 姓名：{self.student_info.name}, 所在院系：{self.student_info.department}, 班级：{self.student_info.class_name}, " \
               f"平均学分绩点：{self.academic_data.gpa:.2f}, 累计不及格课程：{self.academic_data.failed_credits}"


class StudentManager:
    def __init__(self):
        self.students = {}  # 学生信息字典，以学号为键

    def add_student(self, student):
        self.students[student.student_info.student_id] = student

    def get_student_info(self, student_id):
        return self.students.get(student_id, None)

    def add_course_to_student(self, student_id, course):
        student = self.get_student_info(student_id)
        if student:
            student.academic_data.add_course(course)
            


class StudentGUI:
    def __init__(self, master):
        self.master = master
        self.master.title("学生学情管理系统")
        self.student_manager = StudentManager()

        # 创建输入框和标签
        self.id_label = tk.Label(master, text="学号:")
        self.id_label.grid(row=0, column=0, padx=10, pady=5)
        self.id_entry = tk.Entry(master)
        self.id_entry.grid(row=0, column=1, padx=10, pady=5)

        self.name_label = tk.Label(master, text="姓名:")
        self.name_label.grid(row=1, column=0, padx=10, pady=5)
        self.name_entry = tk.Entry(master)
        self.name_entry.grid(row=1, column=1, padx=10, pady=5)

        self.department_label = tk.Label(master, text="院系:")
        self.department_label.grid(row=2, column=0, padx=10, pady=5)
        self.department_entry = tk.Entry(master)
        self.department_entry.grid(row=2, column=1, padx=10, pady=5)

        self.class_label = tk.Label(master, text="班级:")
        self.class_label.grid(row=3, column=0, padx=10, pady=5)
        self.class_entry = tk.Entry(master)
        self.class_entry.grid(row=3, column=1, padx=10, pady=5)

        # 创建按钮
        self.add_button = tk.Button(master, text="添加学生", command=self.add_student)
        self.add_button.grid(row=4, column=0, padx=10, pady=5)

        self.add_grade_button = tk.Button(master, text="录入学生成绩", command=self.add_grade)
        self.add_grade_button.grid(row=4, column=1, padx=10, pady=5)

        self.query_button = tk.Button(master, text="查询学生", command=self.query_student)
        self.query_button.grid(row=4, column=2, padx=10, pady=5)

        # 创建文本框用于显示查询结果
        self.result_text = tk.Text(master, height=10, width=50)
        self.result_text.grid(row=5, column=0, columnspan=3, padx=10, pady=5)

        # 添加“输入表格”按钮
        self.import_button = tk.Button(master, text="输入表格", command=self.import_from_file)
        self.import_button.grid(row=4, column=3, padx=10, pady=5)

    def add_student(self):
        student_id = self.id_entry.get()
        name = self.name_entry.get()
        department = self.department_entry.get()
        class_name = self.class_entry.get()

        if student_id and name and department and class_name:
            student_info = StudentInfo(student_id, name, department, class_name)
            academic_data = AcademicData()
            student = Student(student_info, academic_data)
            self.student_manager.add_student(student)
            messagebox.showinfo("提示", "学生信息添加成功！")
        else:
            messagebox.showerror("错误", "请输入完整的学生信息！")

    def add_grade(self):
        student_id = self.id_entry.get()
        student = self.student_manager.get_student_info(student_id)
        if student:
            course_name = simpledialog.askstring("输入", "课程名称:")
            credits = simpledialog.askinteger("输入", "学分:")
            grade = simpledialog.askinteger("输入", "成绩:")
            is_repeated = simpledialog.askinteger("输入", "是否重修(0-否, 1-是):")
            if course_name and credits and grade is not None and is_repeated is not None:
                course = Course(course_name, credits, grade, bool(is_repeated))
                self.student_manager.add_course_to_student(student_id, course)
                messagebox.showinfo("提示", "学生成绩录入成功！")
        else:
            messagebox.showerror("错误", "未找到该学生信息！")
 
    def query_student(self):
        student_id = self.id_entry.get()
        student = self.student_manager.get_student_info(student_id)
        if student:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, str(student))
            self.result_text.insert(tk.END, "\n已修课程信息：\n")
            for course in student.academic_data.courses_taken:
                self.result_text.insert(tk.END, str(course) + "\n")
        else:
            messagebox.showerror("错误", "未找到该学生信息！")

    def import_from_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx"), ("All files", "*.*")])
        if file_path:
            self.import_students_from_excel(file_path)
            messagebox.showinfo("提示", "学生信息已从表格中导入成功！")

    def import_students_from_excel(self, file_path):
        df = pd.read_excel(file_path)
        for index, row in df.iterrows():
            student_id = str(row['学号'])
            name = row['姓名']
            department = row['院系']
            class_name = row['班级']
            # 检查学生是否已存在，若不存在则创建新学生信息
            if student_id not in self.student_manager.students:
                student_info = StudentInfo(student_id, name, department, class_name)
                academic_data = AcademicData()
                student = Student(student_info, academic_data)
                self.student_manager.add_student(student)
            else:
                student = self.student_manager.get_student_info(student_id)
        
            # 添加课程信息
            course_name = row['课程名称']
            course_credits = row['课程学分']
            course_grade = row['成绩']
            course_is_repeated = row['是否重修'] == '是'
            course = Course(course_name, course_credits, course_grade, course_is_repeated)
            self.student_manager.add_course_to_student(student_id, course)
        


if __name__ == "__main__":
    root = tk.Tk()
    app = StudentGUI(root)
    root.mainloop()